﻿using K9Nano.Dependency;
using K9Nano.Domain.Entities;
using K9Nano.Exceptions;
using K9Nano.Extensions;
using K9Nano.Reporting;
using K9Nano.Session;
using Microsoft.EntityFrameworkCore;

namespace K9Nano.Domain.Reporting;

public class ReportStore(ReportDbContext db, IUserContextAccessor userContextAccessor) : IReportStore, IScopedDependency
{
    public virtual async Task DeleteAsync(int id, CancellationToken cancellation)
    {
        await db.Reports.Where(a => a.Id == id).ExecuteDeleteAsync(cancellation);
    }

    public virtual async Task<IEnumerable<ReportSummary>> GetAllReportsAsync(CancellationToken cancellation)
    {
        return await db.Reports.AsNoTracking()
            .Where(a => a.IsEnabled)
            .Select(a => new ReportSummary(a.Id, a.DisplayName, a.Description))
            .ToListAsync(cancellation);
    }

    public virtual async Task<Report?> GetAsync(int id, CancellationToken cancellation)
    {
        var entity = await db.Reports.AsNoTracking()
            .FirstOrDefaultAsync(a => a.Id == id, cancellation);
        if (entity == null) return null;
        return new Report
        {
            Id = entity.Id,
            DisplayName = entity.DisplayName,
            Description = entity.Description,
            FormItems = entity.Fields,
            Columns = entity.Columns,
            SqlText = entity.SqlText,
            TotalSqlText = entity.TotalSqlText,
            IsEnabled = entity.IsEnabled,
        };
    }

    public virtual async Task SaveAsync(Report report, CancellationToken cancellation)
    {
        ReportEntity entity;
        if (report.Id <= 0)
        {
            entity = new()
            {
                DisplayName = report.DisplayName,
                Description = report.Description,
                Fields = report.FormItems.AsList(),
                Columns = report.Columns.AsList(),
                SqlText = report.SqlText,
                TotalSqlText = report.TotalSqlText,
                IsEnabled = report.IsEnabled,
                CreatedAt = DateTime.Now,
                CreatedBy = userContextAccessor.CurrentUser?.UserId ?? 0,
            };
            db.Add(entity);
        }
        else
        {
            entity = await db.Reports
               .FirstOrDefaultAsync(a => a.Id == report.Id, cancellation)
               ?? throw FriendlyException.BadRequest("报表不存在");
            entity.DisplayName = report.DisplayName;
            entity.Description = report.Description;
            entity.Fields = report.FormItems.AsList();
            entity.Columns = report.Columns.AsList();
            entity.SqlText = report.SqlText;
            entity.TotalSqlText = report.TotalSqlText;
            entity.IsEnabled = report.IsEnabled;
            entity.UpdatedAt = DateTime.Now;
            entity.UpdatedBy = userContextAccessor.CurrentUser?.UserId ?? 0;
        }

        await db.SaveChangesAsync(cancellation);
    }

    public virtual async Task<bool> SetStatusAsync(int id, bool isEnabled, CancellationToken cancellation)
    {
        var entity = await db.Reports
               .FirstOrDefaultAsync(a => a.Id == id, cancellation)
               ?? throw FriendlyException.BadRequest("报表不存在");
        entity.IsEnabled = isEnabled;
        return await db.SaveChangesAsync(cancellation) > 0;
    }
}
